﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Text;
using System.Web;
using System.Web.Configuration;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Http;
using EntityFrameworks.Entity.Core.Extensions;
namespace EntityFrameworks.Web.Core.Attributes
{

    /// <summary>   
    /// 基本验证Attribtue，用以WebApi请求的权限处理   
    /// </summary>   
    public class BasicAuthenticationAttribute : ActionFilterAttribute
    {
        #region Consts & Fields
        /// <summary>
        /// token存储块
        /// </summary>
        MemcachedCache icache = new MemcachedCache();
        /// <summary>
        /// token不合法
        /// </summary>
        const string TOKENBADERR = "The request has no token or toke id expired,it is invalid !";
        /// <summary>
        /// 页面需要授权
        /// </summary>
        const string UNAUTHORIZEDERR = "The request is Unauthorized,you need a token!";
        #endregion

        /// <summary>   
        /// 检查用户是否有该WebApi请求执行的权限   
        /// </summary>   
        /// <param name="actionContext"></param>   
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            //判断发过来的请求报文头里面是不是设置了Set-Cookie
            if (actionContext.Request.Headers.Contains("Cookie"))
            {
                var accessToken = actionContext.Request.Headers.GetCookies("token_list")[0].Cookies[0].Values;

                //解密用户token值，看有没有登录
                var tokenValue = accessToken["access_token"];

                if (ValidateToken(tokenValue))
                {
                    base.OnActionExecuting(actionContext);
                }
                else
                {
                    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
                    actionContext.Response.Content = new StringContent(TOKENBADERR
                        , Encoding.UTF8
                        , "text/plain");//Html格式
                }
            }
            else
            {
                //检查web.config配置是否要求权限校验   
                if (WebConfigurationManager.AppSettings["WebApiAuthenticatedFlag"] == null)
                    throw new ArgumentException("请配置WebApiAuthenticatedFlag节点");

                bool isRquired = (WebConfigurationManager.AppSettings["WebApiAuthenticatedFlag"].ToString() == "true");
                if (isRquired)
                {
                    //如果请求Header不包含token，则判断是否是匿名调用   
                    var attr = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                    bool isAnonymous = attr.Any(a => a is AllowAnonymousAttribute);

                    //是匿名用户，则继续执行；非匿名用户，抛出“未授权访问”信息   
                    if (isAnonymous)
                    {
                        base.OnActionExecuting(actionContext);
                    }
                    else
                    {
                        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
                        actionContext.Response.Content = new StringContent(UNAUTHORIZEDERR
                            , Encoding.UTF8
                            , "text/plain");//Html格式
                    }
                }
                else
                {
                    base.OnActionExecuting(actionContext);
                }
            }
        }

        /// <summary>
        /// 验证是否登录授权
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        bool ValidateToken(string token)
        {
            if (!string.IsNullOrEmpty(token))
            {
                var model = icache.Get(token);
                return model != null ? true : false;
            }
            return false;
        }
    }
    public class MemcachedCache
    {
        readonly static Dictionary<string, string> library = new Dictionary<string, string>();
        public void Add(string token, string value)
        {
            if (!library.ContainsKey(token))
            {
                library.Add(token, value);
            }
        }
        public void Remove(string token)
        {
            library.Remove(token);
        }

        public string Get(string token)
        {
            if (!library.ContainsKey(token))
                return null;
            return library[token];
        }
    }

}